﻿using System;
using System.Diagnostics;
using System.Threading;
using Wolfpack.Core.Checks;
using Wolfpack.Core.Interfaces.Entities;
using Wolfpack.Core.Notification;

namespace Wolfpack.Contrib.Checks.NServiceBusPerformanceCounters
{
    public class NServiceBusCriticalTimeCounterCheck : ThresholdCheckBase<NServiceBusCriticalTimeCounterCheckConfig>
    {
        protected PerformanceCounter _counter;

        private const string CategoryName = "NServiceBus";
        private const string CounterName = "Critical Time";

        /// <summary>
        /// default ctor
        /// </summary>
        public NServiceBusCriticalTimeCounterCheck(NServiceBusCriticalTimeCounterCheckConfig config)
            : base(config)
        {
        }

        public override void Initialise()
        {
            _counter = string.IsNullOrEmpty(_config.MachineName)
                ? new PerformanceCounter(CategoryName, CounterName, _config.InstanceName)
                : new PerformanceCounter(CategoryName, CounterName, _config.InstanceName, _config.MachineName);
        }

        public override void Execute()
        {
            var sample = _counter.NextSample();
            Thread.Sleep(500);
            var sample2 = _counter.NextSample();
            var value = Math.Round(CounterSampleCalculator.ComputeCounterValue(sample, sample2));

            Publish(NotificationRequestBuilder.For(_config.NotificationMode, HealthCheckData.For(
                Identity,
                "The maximum age of message in {0} is {1} seconds", _config.InstanceName, value)
                .ResultCountIs(value)
                ).Build());                
        }

        protected override PluginDescriptor BuildIdentity()
        {
            return new PluginDescriptor
            {
                Description = "Reports the NServiceBus Critical Time counter for " + _config.InstanceName + ". The Critical Time counter monitors the age of the oldest message in the queue. This takes into account the whole chain from the message being sent on the client machine until successfully processed by the server. You should define a SLA for each of your endpoints and use the CriticalTime counter to make sure that you're adhering to it.",
                TypeId = new Guid("92F62A98-5007-451A-9222-2B10DC44F635"),
                Name = _config.FriendlyId
            };
        }
    }
}
